#include "ContextEGL1_1.h"
#include "../infLib/infLib.h"

ContextEGL1_1::ContextEGL1_1()
{

}

ContextEGL1_1::~ContextEGL1_1()
{

}

bool ContextEGL1_1::Init(void* hWnd, int w, int h, int bpp, int multiSample, int flag)
{
    this->hWnd = (HWND)hWnd;
    eglWindow = (NativeWindowType)hWnd;

#ifdef _WIN32
    hDC = GetDC(this->hWnd);
    if (!hDC)
    {
        inf::fatal_error( "Failed to create the device context" );
        return false;
    }
    eglDisplay = eglGetDisplay((NativeDisplayType)hDC);
    if(eglDisplay == EGL_NO_DISPLAY)
        eglDisplay = eglGetDisplay((NativeDisplayType) EGL_DEFAULT_DISPLAY);
#else
    eglDisplay = eglGetDisplay((NativeDisplayType)EGL_DEFAULT_DISPLAY);
#endif
    if(eglDisplay == EGL_NO_DISPLAY)
    {
        TestEGLError("eglGetDisplay returned EGL_NO_DISPLAY\n");
        return false;
    }

    EGLint iMajorVersion, iMinorVersion;
    if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
    {
        TestEGLError("eglInitialize() failed");
        return false;
    }

    eglBindAPI(EGL_OPENGL_ES_API);

    int i = 0;
    pi32ConfigAttribs[i++] = EGL_RED_SIZE;
    pi32ConfigAttribs[i++] = 8;
    pi32ConfigAttribs[i++] = EGL_GREEN_SIZE;
    pi32ConfigAttribs[i++] = 8;
    pi32ConfigAttribs[i++] = EGL_BLUE_SIZE;
    pi32ConfigAttribs[i++] = 8;
    pi32ConfigAttribs[i++] = EGL_ALPHA_SIZE;
    pi32ConfigAttribs[i++] = (flag&CF_ALPHA) ? 8 : EGL_DONT_CARE;
    pi32ConfigAttribs[i++] = EGL_DEPTH_SIZE;
    pi32ConfigAttribs[i++] = (flag&CF_DEPTH) ? 16 : EGL_DONT_CARE;
    pi32ConfigAttribs[i++] = EGL_STENCIL_SIZE;
    pi32ConfigAttribs[i++] = (flag&CF_STENCIL) ? 8 : EGL_DONT_CARE;
    pi32ConfigAttribs[i++] = EGL_SAMPLE_BUFFERS;
    pi32ConfigAttribs[i++] = (multiSample>0) ? 1 : 0;
    pi32ConfigAttribs[i++] = EGL_SURFACE_TYPE;
    pi32ConfigAttribs[i++] = EGL_WINDOW_BIT;
    pi32ConfigAttribs[i++] = EGL_NONE;

    /*
    Step 4 - Find a config that matches all requirements.
    eglChooseConfig provides a list of all available configurations
    that meet or exceed the requirements given as the second
    argument. In most cases we just want the first config that meets
    all criteria, so we can limit the number of configs returned to 1.
    */
    int iConfigs;
    if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
    {
        TestEGLError("eglChooseConfig() failed");
        return false;
    }

    eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL);

    if(eglSurface == EGL_NO_SURFACE)
    {
        eglGetError(); // Clear error
        eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, NULL, NULL);
    }

    if (!TestEGLError("eglCreateWindowSurface"))
    {
        return false;
    }

    eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL);
    if (!TestEGLError("eglCreateContext"))
    {
        return false;
    }

    this->w = w;
    this->h = h;
    MakeCurrent();

    return true;
}


void ContextEGL1_1::Release()
{
    //eglDestroyContext(eglDisplay, eglContext);
    //eglDestroySurface(eglDisplay, eglSurface);

    eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglTerminate(eglDisplay);

#ifdef _WIN32
    // Release the device context
    if (hDC) ReleaseDC(hWnd, hDC);
#endif
}

